package com.x.mapper.provider;

import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import tk.mybatis.mapper.entity.EntityTable;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author 252944454@qq.com
 * @date 2016/12/14
 */
public class DtoExampleProvider extends MapperTemplate {

    public DtoExampleProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }

    public String selectDtoByExample(MappedStatement ms) {

        Class<?> entityClass = getEntityClass(ms);

        getDtoClass(ms);

        //将返回值修改为实体类型
        setResultType(ms, entityClass);




        StringBuilder sql = new StringBuilder("SELECT ");
        sql.append("<if test=\"param1!=null and param1.distinct\">distinct</if>");
        //支持查询指定列
        sql.append(exampleSelectColumns(entityClass));
        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));

        sql.append(exampleWhereClause());
        sql.append(exampleOrderBy(entityClass));

        return sql.toString();
    }

    private void getDtoClass(MappedStatement ms) {

        Class<?> mapperClass = getMapperClass(ms.getId());
        Method method = null;
        try {
             method = mapperClass.getMethod("selectDtoByExample",Object.class,Class.class);
        } catch (NoSuchMethodException e) {
        }

        if(method==null){
            return;
        }
        method.getParameterTypes()[1].getGenericInterfaces()[0].getTypeName();

        return;

    }


    /**
     * example支持查询指定列时
     *
     * @return
     */
    public static String exampleSelectColumns(Class<?> entityClass) {
        StringBuilder sql = new StringBuilder();
        sql.append("<if test=\"@tk.mybatis.mapper.util.OGNL@hasSelectColumns(param1)\">");
        sql.append("<foreach collection=\"param1.selectColumns\" item=\"selectColumn\" separator=\",\">");
        sql.append("${selectColumn}");
        sql.append("</foreach>");
        sql.append("</if>");
        //不支持指定列的时候查询全部列
        sql.append("<if test=\"@tk.mybatis.mapper.util.OGNL@hasNoSelectColumns(param1)\">");
        sql.append(SqlHelper.getAllColumns(entityClass));
        sql.append("</if>");
        return sql.toString();
    }




    public static String exampleWhereClause() {
        return "<if test=\"param1 != null\">" +
                "<where>\n" +
                "  <foreach collection=\"param1.oredCriteria\" item=\"criteria\" separator=\"or\">\n" +
                "    <if test=\"criteria.valid\">\n" +
                "      <trim prefix=\"(\" prefixOverrides=\"and\" suffix=\")\">\n" +
                "        <foreach collection=\"criteria.criteria\" item=\"criterion\">\n" +
                "          <choose>\n" +
                "            <when test=\"criterion.noValue\">\n" +
                "              and ${criterion.condition}\n" +
                "            </when>\n" +
                "            <when test=\"criterion.singleValue\">\n" +
                "              and ${criterion.condition} #{criterion.value}\n" +
                "            </when>\n" +
                "            <when test=\"criterion.betweenValue\">\n" +
                "              and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}\n" +
                "            </when>\n" +
                "            <when test=\"criterion.listValue\">\n" +
                "              and ${criterion.condition}\n" +
                "              <foreach close=\")\" collection=\"criterion.value\" item=\"listItem\" open=\"(\" separator=\",\">\n" +
                "                #{listItem}\n" +
                "              </foreach>\n" +
                "            </when>\n" +
                "          </choose>\n" +
                "        </foreach>\n" +
                "      </trim>\n" +
                "    </if>\n" +
                "  </foreach>\n" +
                "</where>" +
                "</if>";
    }

    public static String exampleOrderBy(Class<?> entityClass) {
        StringBuilder sql = new StringBuilder();
        sql.append("<if test=\"param1!=null and param1.orderByClause != null\">");
        sql.append("order by ${param1.orderByClause}");
        sql.append("</if>");
        String orderByClause = EntityHelper.getOrderByClause(entityClass);
        if (orderByClause.length() > 0) {
            sql.append("<if test=\"param1.orderByClause == null\">");
            sql.append("ORDER BY " + orderByClause);
            sql.append("</if>");
        }
        return sql.toString();
    }




}
